package com.eye.catcher.service.generate.impl;

import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eye.catcher.common.RedisUtils;
import com.eye.catcher.constants.RedisConstants;
import com.eye.catcher.constants.SbCode;
import com.eye.catcher.entity.TYwDaBaseInfo;
import com.eye.catcher.mapper.TYwDaBaseInfoMapper;
import com.eye.catcher.service.generate.ITYwDaBaseInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eye.catcher.system.role.param.RoleDto;
import com.eye.catcher.system.user.param.UserLoginInfo;
import com.eye.catcher.system.yw.Info.param.BaseInfoDto;
import com.eye.catcher.system.yw.Info.param.BaseInfoPage;
import com.eye.catcher.utils.DownloadUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 基地表 服务实现类
 * </p>
 *
 * @author huzhiwei
 * @since 2022-05-12
 */
@Slf4j
@Service
public class TYwDaBaseInfoServiceImpl extends ServiceImpl<TYwDaBaseInfoMapper, TYwDaBaseInfo> implements ITYwDaBaseInfoService {

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private TYwDaBaseInfoMapper baseInfoMapper;

    @Value("${base.all-permissions.roleId}")
    private String baseAllPermissionsRoleId;

    @Value("${download.template.url-path}")
    private String downloadTemplateUrlPath;

    @Override
    public void addBaseInfo(TYwDaBaseInfo info) {
        UserLoginInfo userLoginInfo = (UserLoginInfo)redisUtils.get(RedisConstants.USER_INFO_EXPIRE.getKey()+info.getCreateUserId());
        info.setCreateUserId(info.getCreateUserId());
        info.setCreateUserName(userLoginInfo.getUserDto().getUserName());
        info.setCreateLoginName(userLoginInfo.getUserDto().getLoginName());
        info.setCreateTime(LocalDateTime.now());
        info.setSource(SbCode.DATA_SOURCE_CREATE.getCode());
        this.save(info);
    }

    @Override
    public void editBaseInfo(TYwDaBaseInfo info) {
        UserLoginInfo userLoginInfo = (UserLoginInfo)redisUtils.get(RedisConstants.USER_INFO_EXPIRE.getKey()+info.getUpdateUserId());
        info.setUpdateUserId(info.getCreateUserId());
        info.setUpdateUserName(userLoginInfo.getUserDto().getUserName());
        info.setUpdateLoginName(userLoginInfo.getUserDto().getLoginName());
        info.setUpdateTime(LocalDateTime.now());
        this.updateById(info);
    }

    @Override
    public void deleteByIds(String ids) {
        this.removeByIds(Arrays.asList(ids.split(",")));
    }

    @Override
    public Object getAllList(BaseInfoDto baseInfo) {
        QueryWrapper<TYwDaBaseInfo> wrapper = Wrappers.query();
        //组装查询条件
        this.appendWrapper(wrapper,baseInfo);

        wrapper.orderByAsc(" cast(BASE_CODE as unsigned int)  ");
        return baseInfoMapper.list(wrapper);
    }

    @Override
    public Object getPageList(BaseInfoPage baseInfoPage) {
        Page<TYwDaBaseInfo> page=new Page<>(baseInfoPage.getPage().getPageNum(),baseInfoPage.getPage().getPageSize());
        QueryWrapper<TYwDaBaseInfo> wrapper = Wrappers.query();
        //组装查询条件
        this.appendWrapper(wrapper,baseInfoPage.getBaseInfo());

        wrapper.orderByAsc(" cast(BASE_CODE as unsigned int)  ");
        //list
        IPage<TYwDaBaseInfo> returnPage = baseInfoMapper.page(page, wrapper);
        //总数
        returnPage.setTotal(this.count(wrapper));
        return returnPage;
    }
    @Override
    public Object getBaseInfoByCode(String code){
        QueryWrapper<TYwDaBaseInfo> wrapper = Wrappers.query();
        wrapper.eq("BASE_CODE",code);
        return this.getOne(wrapper);
    }
    @Override
    public String exportBaseTemplate(HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException {
        String urlPath = downloadTemplateUrlPath + "/template";
        String fileName = "基地导入模板.xlsx";
        InputStream inputStream = new FileInputStream(urlPath+"/"+fileName);
        DownloadUtils.downloadFile(request, response, inputStream, fileName);
        return null;
    }

    @Override
    public String uploadBaseTemplate(MultipartFile file,String userId) throws IOException {
        UserLoginInfo userLoginInfo = (UserLoginInfo)redisUtils.get(RedisConstants.USER_INFO_EXPIRE.getKey()+userId);
        List<TYwDaBaseInfo> baseInfoList = new ArrayList<>();
        ExcelUtil.readBySax(file.getInputStream(), 0, (sheetIndex, rowIndex, list) -> {
            if((null == list || list.size() != 15) || sheetIndex != 0 || rowIndex == 0){
               return;
            }
//            System.out.println(sheetIndex); // 输出第几张表格 从0开始
//            System.out.println(rowIndex); // 输出第几行数据 从0开始 第一行一般为表头
//            System.out.println(list); // 每行的数据 封装在一个列表里面
            baseInfoList.add(
                new TYwDaBaseInfo(
                    this.getStringParam(list.get(0)),
                    this.getStringParam(list.get(1)),
                    this.getStringParam(list.get(2)),
                    this.getStringParam(list.get(4)),
                    this.getStringParam(list.get(5)),
                    this.getStringParam(list.get(3)),
                    this.getStringParam(list.get(6)),
                    this.getStringParam(list.get(7)),
                    this.getStringParam(list.get(8)),
                    this.getStringParam(list.get(9)),
                    this.getStringParam(list.get(10)),
                    this.getStringParam(list.get(11)),
                    this.getStringParam(list.get(12)),
                    this.getStringParam(list.get(13)),
                    Integer.parseInt(
                        null == this.getStringParam(list.get(14)) ?
                            ""+new Date().getYear() : this.getStringParam(list.get(14))
                    ),
                    userId,
                    userLoginInfo.getUserDto().getLoginName(),
                    userLoginInfo.getUserDto().getUserName(),
                    LocalDateTime.now(),
                    (int) rowIndex,
                    SbCode.DATA_SOURCE_IMPORT.getCode()
                )
            );
        });
        if(baseInfoList.size() > 0 ){
            this.saveBatch(baseInfoList);
        }
        return null;
    }

    private String getStringParam(Object o) {
        if(null == o){
            return null;
        }
        if(StringUtils.isNotEmpty(String.valueOf(o))){
            return String.valueOf(o);
        }
        return null;
    }

    private void appendWrapper(QueryWrapper<TYwDaBaseInfo> wrapper, BaseInfoDto baseInfo) {

        if(StringUtils.isNotEmpty(baseInfo.getId())){
            wrapper.eq("ID",Integer.parseInt(baseInfo.getId()));
        }
        if(StringUtils.isNotEmpty(baseInfo.getBaseCode())){
            wrapper.eq("BASE_CODE",baseInfo.getBaseCode());
        }
        if(StringUtils.isNotEmpty(baseInfo.getBaseName())){
            wrapper.like("BASE_NAME",baseInfo.getBaseName());
        }
        if(StringUtils.isNotEmpty(baseInfo.getUserId())){
            UserLoginInfo userLoginInfo = (UserLoginInfo)redisUtils.get(RedisConstants.USER_INFO_EXPIRE.getKey()+baseInfo.getUserId());
            if(!"admin".equals(userLoginInfo.getUserDto().getLoginName())){
                Set<String> rolesSet =new HashSet<>(
                        userLoginInfo.getRoleDtoList().stream().map(RoleDto::getId).collect(Collectors.toList())
                );
                if(!rolesSet.contains(baseAllPermissionsRoleId)){
                    wrapper.eq("ID",userLoginInfo.getUserDto().getBaseId());
                }
            }
        }
    }
}
